﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Guoc.BigMall.Infrastructure.WeChat.Entitys;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Xml;
namespace Guoc.BigMall.Infrastructure.WeChat
{
   public abstract class WeChatMessageHandler
    {
       public ResponseMessage Handler(Stream stream)
       {
           byte[] bytes = new byte[stream.Length];
           stream.Read(bytes, 0, (int)stream.Length);
           var requestXml = System.Text.Encoding.UTF8.GetString(bytes);
           return Handler(requestXml);
       }

       public ResponseMessage Handler(string requestXml)
       {             
           if (string.IsNullOrEmpty(requestXml)) {
               return new ResponseMessageEmptyText();
           }

           var request = Deserialize<RequestMessage>(requestXml);
           ResponseMessage response = new ResponseMessageEmptyText(request);

           switch (request.MsgType)
           {
               case "text":
                   var requestMessageText = Deserialize<RequestMessageText>(requestXml);
                   response = OnRequestMessageText(requestMessageText);
                   break;
               case "location":
                   break;
               case "image":
                   break;
               case "voice":
                   break;
               case "video":
                   break;
               case "link":
                   break;
               case "event":
                   response = HandlerEvent(requestXml);
                   break;
               default:
                   break;
           }

           return response;
          
       }

       private ResponseMessage HandlerEvent(string requestXml) 
       {
           RequestMessageEvent requestMessage = Deserialize<RequestMessageEvent>(requestXml);
           ResponseMessage response = MakeMessageEmptyText(requestMessage);
           switch (requestMessage.Event)
           {
               case "subscribe":
                   var scanSubScribe =  Deserialize<RequestMessageEvent_SubscribeScan>(requestXml);
                   if (!string.IsNullOrEmpty(scanSubScribe.EventKey)&& scanSubScribe.EventKey.StartsWith("qrscene_") && !string.IsNullOrEmpty(scanSubScribe.Ticket))
                   {
                       response = OnRequestMessageEvent_SubscribeScan(scanSubScribe);
                   }
                   else
                   {
                       response = OnRequestMessageEvent_Subscribe(Deserialize<RequestMessageEvent_Subscribe>(requestXml));
                   }                  
                   break;
               case "unsubscribe":                  
                   response = OnRequestMessageEvent_UnSubscribe(Deserialize<RequestMessageEvent_UnSubscribe>(requestXml));
                   break;
               case "click":
                   response = OnRequestMessageEvent_Click(Deserialize<RequestMessageEvent_Click>(requestXml));
                   break;
               case "view":
                   response = OnRequestMessageEvent_View(Deserialize<RequestMessageEvent_View>(requestXml));
                   break;
               case "scan":
                   response = OnRequestMessageEvent_Scan(Deserialize<RequestMessageEvent_Scan>(requestXml));
                   break;
               default:
                   break;
           }
           return response;
       }

       /// <summary>
       ///  反序列化消息节点
       /// </summary>
       /// <typeparam name="T"></typeparam>
       /// <param name="requestXml"></param>
       /// <returns></returns>
       private T Deserialize<T>(string requestXml) {          
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(requestXml)));                 
       }

        #region 消息事件
       /// <summary>
       ///  处理文本请求事件
       /// </summary>
       /// <param name="requestMessage"></param>
       /// <returns></returns>
       public virtual ResponseMessage OnRequestMessageText(RequestMessageText requestMessage)
       {
           return new ResponseMessageEmptyText(requestMessage);            
       }

       /// <summary>
       ///  关注事件
       /// </summary>
       /// <param name="requestEvent"></param>
       /// <returns></returns>
       public virtual ResponseMessage OnRequestMessageEvent_Subscribe(RequestMessageEvent_Subscribe requestEvent)
       {
           return MakeMessageEmptyText(requestEvent);    
       }
       /// <summary>
       ///  取消关注事件
       /// </summary>
       /// <param name="requestEvent"></param>
       /// <returns></returns>
       public virtual ResponseMessage OnRequestMessageEvent_UnSubscribe(RequestMessageEvent_UnSubscribe requestEvent)
       {
           return MakeMessageEmptyText(requestEvent);
       }
       /// <summary>
       ///  菜单点击事件
       /// </summary>
       /// <param name="requestEvent"></param>
       /// <returns></returns>
       public virtual ResponseMessage OnRequestMessageEvent_Click(RequestMessageEvent_Click requestEvent)
       {
           return MakeMessageEmptyText(requestEvent);
       }
       /// <summary>
       /// 菜单跳转事件
       /// </summary>
       /// <param name="requestEvent"></param>
       /// <returns></returns>
       public virtual ResponseMessage OnRequestMessageEvent_View(RequestMessageEvent_View requestEvent)
       {
           return MakeMessageEmptyText(requestEvent);
       }
       /// <summary>
       /// 已关注扫码事件
       /// </summary>
       /// <param name="requestEvent"></param>
       /// <returns></returns>
       public virtual ResponseMessage OnRequestMessageEvent_Scan(RequestMessageEvent_Scan requestEvent)
       {
           return MakeMessageEmptyText(requestEvent);
       }
       /// <summary>
       ///  关注扫码事件：针对未关注用户扫二维码
       /// </summary>
       /// <param name="requestEvent"></param>
       /// <returns></returns>
       public virtual ResponseMessage OnRequestMessageEvent_SubscribeScan(RequestMessageEvent_SubscribeScan requestEvent)
       {
           return MakeMessageEmptyText(requestEvent);
       }



       private  ResponseMessage MakeMessageEmptyText(RequestMessageEvent requestEvent)
       {
           return new ResponseMessageEmptyText(requestEvent.FromUserName, requestEvent.ToUserName); 
       }
       private  ResponseMessage MakeMessageEmptyText(string fromUserName,string toUserName)
       {
           return new ResponseMessageEmptyText(fromUserName, toUserName);
       }

        #endregion
    }
}
